package com.zjsru.plan2023.oneday;

/**
 * @Author: cookLee
 * @Date: 2023-09-17
 * 打家劫舍2
 */
public class Rob {

    /**
     * 你是一个专业的小偷，计划偷窃沿街的房屋，每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ，
     * 这意味着第一个房屋和最后一个房屋是紧挨着的。同时，相邻的房屋装有相互连通的防盗系统，如果两间相邻的房屋在同一晚上被小偷闯入，系统会自动报
     * 输入：nums = [2,3,2]
     * 输出：3
     * 解释：你不能先偷窃 1 号房屋（金额 = 2），然后偷窃 3 号房屋（金额 = 2）, 因为他们是相邻的。
     * \
     * 输入：nums = [1,2,3,1]
     * 输出：4
     * 解释：你可以先偷窃 1 号房屋（金额 = 1），然后偷窃 3 号房屋（金额 = 3）。
     *      偷窃到的最高金额 = 1 + 3 = 4 。
     *
     * @param args
     */
    public static void main(String[] args) {
        Rob rob = new Rob();
        int[] nums = new int[]{1,2,3,1};
        System.out.println(rob.rob(nums));
    }

    /**
     * 动态规划
     * @param nums
     * @return int
     */
    public int rob(int[] nums) {
        //1.考虑没有房屋
        if (nums.length == 0) {
            return -1;
        } else if (nums.length == 1) {
            //2.考虑一栋房屋
            return nums[0];
        } else if (nums.length == 2) {
            //3.考虑两栋房屋
            return Math.max(nums[0], nums[1]);
        } else {
            //4.考虑其他可能性
            //4.1如果偷窃了第一间房屋，则不能偷窃最后一间房屋
            //4.2如果偷窃了最后一间房屋，则不能偷窃第一间房屋
            return Math.max(this.helper(0, nums.length - 2, nums), this.helper(1, nums.length - 1, nums));
        }
    }

    /**
     * 计算助手类
     *
     * @param start 开始下标
     * @param end 结束下标
     * @param nums 数组
     * @return int
     */
    private int helper(int start, int end, int[] nums) {
        int first = nums[start];
        int second = Math.max(nums[start], nums[start + 1]);
        //相邻的房屋存在警报器
        for (int i = start + 2; i <= end; i++) {
            int temp = second;
            second = Math.max(first + nums[i], second);
            first = temp;
        }
        return second;
    }
}
